import { defineComponent, ref, reactive } from 'vue';
import _, { debounce } from "lodash";
import styles from "./SearchForm.module.less";
import { analysisRolesAndOr, analysisPermissionsAndOr } from "@/common/auth/auth";
export default defineComponent({
  name: 'searchForm',
  props: {
    fields: {
      type: Object,
      default: () => {
        return {};
      },
    },
    authConfig: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  emits: [
    "confirm",
  ],
  setup(props: any, { emit }) {
    const types: any = {
      input: {
        value: null,
      },
      radios: {
        value: null,
      },
      checkbox: {
        value: [],
      },
      select: {
        value: null,
      },
      select_multiple: {
        value: [],
      },
      select_tree: {
        value: null,
      },
      switch: {
        value: false,
      },
      date: {
        value: null,
      },
      date_range: {
        value: [],
      },
      customer: {
        value: null,
      },
    };
    const cols: any[] = [];
    const form: { [key: string]: any } = reactive({});
    const origin_form: { [key: string]: any } = {};
    for (let x in props.fields) {
      if ((!props.fields?.[x]?.permissions || analysisPermissionsAndOr(props.fields?.[x]?.permissions)) && (!props.fields?.[x]?.roles || analysisRolesAndOr(props.fields?.[x]?.roles))) {
        form[x] = _.cloneDeep(types[props.fields[x].type].value);
        origin_form[x] = _.cloneDeep(types[props.fields[x].type].value);
        let col: any = <div></div>;
        if (props.fields[x].type === 'radios') {
          col = () => {
            return (
              <div class={styles.radioGroup} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <a-radio-group class={styles.value} value={form[x]} onChange={(e: any) => {
                  form[x] = e.target.value; props.fields[x]?.change && props.fields[x]?.change({
                    value: form[x],
                    form,
                    field: props.fields[x]
                  })
                }} {...props.fields[x].attrs}>
                  {
                    props.fields[x].datas.map((x: any) => <a-radio value={x.value}>{x.label}</a-radio>)
                  }
                </a-radio-group>
              </div>
            )
          }
        }
        if (props.fields[x].type === 'checkbox') {
          const checked = ref(false);
          const checkAllChange = (e: any) => {
            checked.value = e.target.checked;
            if (checked.value) {
              form[x] = props.fields[x].datas.map((x: any) => x.value);
            } else {
              form[x] = [];
            }
            props.fields[x]?.change && props.fields[x]?.change({
              value: form[x],
              form,
              field: props.fields[x]
            })
          }
          const checkChange = (e: any) => {
            if (form[x].includes(e)) {
              form[x].splice(form[x].findIndex((y: any) => y === e), 1);
            } else {
              form[x].push(e);
            }
            if (form[x].length === props.fields[x].datas.length) {
              checked.value = true;
            } else {
              checked.value = false;
            }
            props.fields[x]?.change && props.fields[x]?.change({
              value: form[x],
              form,
              field: props.fields[x]
            })
          }
          col = () => {
            return (
              <div class={styles.checkboxGroup} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <div class={styles.value}>
                  <a-checkbox {...props.fields[x].attrs} checked={checked.value} onChange={(e: any) => checkAllChange(e)}>全部</a-checkbox>
                  {
                    props.fields[x].datas.map((y: any) => <a-checkbox checked={form[x].includes(y.value)} onChange={(e: any) => checkChange(y.value)}>{y.label}</a-checkbox>)
                  }
                </div>
              </div>
            )
          }
        }
        if (props.fields[x].type === 'input') {
          col = () => {
            return (
              <div class={styles.input} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <a-input
                  class={styles.value}
                  value={form[x]}
                  onChange={(e: any) => {
                    form[x] = e.target.value; props.fields[x]?.change && props.fields[x]?.change({
                      value: form[x],
                      form,
                      field: props.fields[x]
                    })
                  }}
                  {...props.fields[x].attrs}
                />
              </div>
            )
          }
        }
        if (props.fields[x].type === 'switch') {
          col = () => {
            return (
              <div class={styles.switch} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <a-switch
                  class={styles.aSwitch}
                  checked={form[x] === props.fields?.[x]?.datas?.[0] ?? true}
                  onChange={(e: any) => {
                    form[x] = e ? props.fields?.[x]?.datas?.[0] ?? true : props.fields?.[x]?.datas?.[1] ?? false; props.fields[x]?.change && props.fields[x]?.change({
                      value: form[x],
                      form,
                      field: props.fields[x]
                    })
                  }}
                  {...props.fields[x].attrs}
                />
              </div>
            )
          }
        }
        if (props.fields[x].type === 'select_multiple') {
          col = () => {
            return (
              <div class={styles.select} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <a-select
                  class={styles.value}
                  value={form[x]}
                  mode="multiple"
                  max-tag-count={5}
                  {...props.fields[x].attrs}
                  options={props.fields[x].datas}
                  onChange={(e: any) => {
                    form[x] = e; props.fields[x]?.change && props.fields[x]?.change({
                      value: form[x],
                      form,
                      field: props.fields[x]
                    })
                  }}
                ></a-select>
              </div>
            )
          }
        }
        if (props.fields[x].type === 'select') {
          col = () => {
            return (
              <div class={styles.select} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <a-select
                  class={styles.value}
                  value={form[x]}
                  allowClear={true}
                  {...props.fields[x].attrs}
                  options={props.fields[x].datas}
                  onChange={(e: any) => {
                    form[x] = e; props.fields[x]?.change && props.fields[x]?.change({
                      value: form[x],
                      form,
                      field: props.fields[x]
                    })
                  }}
                ></a-select>
              </div>
            )
          }
        }
        if (props.fields[x].type === 'select_tree') {
          col = () => {
            return (
              <div class={styles.select} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <a-tree-select
                  class={styles.value}
                  value={form[x]}
                  allowClear={true}
                  {...props.fields[x].attrs}
                  tree-data={props.fields[x].datas}
                  onChange={(e: any) => {
                    form[x] = e; props.fields[x]?.change && props.fields[x]?.change({
                      value: form[x],
                      form,
                      field: props.fields[x]
                    })
                  }}
                ></a-tree-select>
              </div>
            )
          }
        }
        if (props.fields[x].type === 'date') {
          col = () => {
            return (
              <div class={styles.dateSelector} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <a-date-picker
                  class={styles.value}
                  value={form[x]}
                  {...props.fields[x].attrs}
                  onChange={(e: any) => {
                    form[x] = e; props.fields[x]?.change && props.fields[x]?.change({
                      value: form[x],
                      form,
                      field: props.fields[x]
                    })
                  }}
                />
              </div>
            )
          }
        }
        if (props.fields[x].type === 'date_range') {
          col = () => {
            return (
              <div class={styles.dateRangeSelector} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                <a-range-picker
                  value={form[x]}
                  {...props.fields[x].attrs}
                  onChange={(e: any) => {
                    form[x] = e; props.fields[x]?.change && props.fields[x]?.change({
                      value: form[x],
                      form,
                      field: props.fields[x]
                    })
                  }}
                />
              </div>
            )
          }
        }
        if (props.fields[x].type === 'customer') {
          col = () => {
            return (
              <div class={styles.dateRangeSelector} style={{ width: props.fields[x].width }}>
                <span class={styles.label}>{props.fields[x].label}</span>
                {
                  props.fields[x].el(form, x)
                }
              </div>
            )
          }
        }
        cols.push(col);
        if (props.fields[x].br) {
          cols.push(() => <br />)
        }
      }
    }
    const reset = () => {
      for (let x in origin_form) {
        form[x] = origin_form[x];
      }
    }
    const submit = debounce(() => {
      let params: { [key: string]: any } = _.cloneDeep(form);
      for (let x in form) {
        if (props.fields[x].type === 'checkbox') {
          if (props.fields[x].datas.length === form[x].length) {
            params[x] = '';
          } else {
            params[x] = form[x];
          }
        } else if (props.fields[x].type === 'date') {
          let dateStr = form[x] ? form[x].$y + '-' + String(form[x].$M + 1).padStart(2, '0') + '-' + String(form[x].$D).padStart(2, '0') : '';
          if (dateStr) {
            let result = new Date(dateStr);
            params[x] = result.getTime() / 1000;
          }
          else {
            params[x] = "";
          }
        } else if (props.fields[x].type === 'date_range') {
          if (form[x]?.length > 0) {
            params[x][0] = form[x][0] ? (form[x][0].$y + '-' + String(form[x][0].$M + 1).padStart(2, '0') + '-' + String(form[x][0].$D).padStart(2, '0')) : '';
            params[x][1] = form[x][1] ? (form[x][1].$y + '-' + String(form[x][1].$M + 1).padStart(2, '0') + '-' + String(form[x][1].$D).padStart(2, '0')) : '';
          } else {
            params[x] = [];
          }
        } else if (props.fields[x].type === 'customer') {
          props.fields[x].format ? (params[x] = props.fields[x].format(form[x])) : (params[x] = form[x]);
        } else {
          params[x] = form[x];
        }
      }
      emit('confirm', params);
    }, 300, { leading: true, trailing: false })
    const searchForm = () => (
      <div class={styles.searchForm}>
        {cols.map(x => (<x />))}
        <div class={styles.btnGroup}>
          <a-button class={styles.btn} onClick={() => { reset() }}>重置</a-button>
          <a-button type="primary" class={styles.btn} onClick={() => { submit() }}>搜索</a-button>
        </div>
      </div>
    )
    return {
      searchForm,
    }
  },
  render() {
    return <this.searchForm></this.searchForm>
  }
})